package com.hzbc.faceattendance.service.impl;

import com.hzbc.faceattendance.config.WechatConfig;
import com.hzbc.faceattendance.model.AdminUser;
import com.hzbc.faceattendance.model.SystemConfig;
import com.hzbc.faceattendance.repository.UserRepository;
import com.hzbc.faceattendance.service.IWechatEventService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class WechatEventServiceImpl implements IWechatEventService {

    @Autowired
    private WechatConfig wechatConfig;

    @Autowired
    private SystemConfig systemConfig;

    @Autowired
    private UserRepository userRepository;

    /**
     * 微信公众号开发配置的Token
     */
    private String getToken() {
        // 建议从SystemConfig中获取，这里先硬编码
        return "your_wechat_token";
    }

    @Override
    public boolean checkSignature(String signature, String timestamp, String nonce) {
        String[] arr = new String[]{getToken(), timestamp, nonce};
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (String s : arr) {
            content.append(s);
        }
        String temp = DigestUtils.md5DigestAsHex(content.toString().getBytes());
        return temp.equals(signature);
    }

    @Override
    public String processEvent(HttpServletRequest request) throws Exception {
        // 读取请求体
        String xmlData = readRequestBody(request);
        log.info("收到微信事件推送: {}", xmlData);

        // 解析XML
        Map<String, String> eventMap = parseXml(xmlData);
        String eventType = eventMap.get("Event");
        String openid = eventMap.get("FromUserName");

        // 处理不同类型事件
        switch (eventType) {
            case "subscribe":
                handleSubscribeEvent(openid, eventMap);
                break;
            case "unsubscribe":
                handleUnsubscribeEvent(openid);
                break;
            default:
                log.info("未处理的事件类型: {}", eventType);
        }

        // 返回成功响应
        return "<xml><ToUserName><![CDATA[" + eventMap.get("FromUserName") + "]]></ToUserName><FromUserName><![CDATA[" + eventMap.get("ToUserName") + "]]></FromUserName><CreateTime>" + new Date().getTime() + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[success]]></Content></xml>";
    }

    /**
     * 处理关注事件
     */
    private void handleSubscribeEvent(String openid, Map<String, String> eventMap) {
        log.info("用户关注: {}", openid);

        // 查询用户是否已存在
        AdminUser user = userRepository.findByWcOpenId(openid).orElse(null);

        if (user == null) {
            // 新用户注册
            user = new AdminUser();
            user.setWcOpenId(openid);
            user.setUsername("wechat_" + openid.substring(0, 8));
            user.setPassword("wechat_default_password"); // 实际项目需要加密
            user.setStatus(1); // 1-正常
        } else {
            // 更新用户状态
            user.setStatus(1);
        }

        // 如果是扫描带参数二维码关注，获取场景值
        String eventKey = eventMap.get("EventKey");
        if (eventKey != null && eventKey.startsWith("qrscene_")) {
            String sceneId = eventKey.substring(8);
            log.info("关注场景值: {}", sceneId);
            // 可以根据场景值进行不同处理
        }

        userRepository.save(user);

        // TODO: 发送欢迎消息
    }

    /**
     * 处理取消关注事件
     */
    private void handleUnsubscribeEvent(String openid) {
        log.info("用户取消关注: {}", openid);

        AdminUser user = userRepository.findByWcOpenId(openid).orElse(null);
        if (user != null) {
            user.setStatus(0); // 0-禁用
            userRepository.save(user);
        }
    }

    /**
     * 读取请求体
     */
    private String readRequestBody(HttpServletRequest request) throws IOException {
        BufferedReader reader = request.getReader();
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }

    /**
     * 解析XML数据
     */
    private Map<String, String> parseXml(String xmlData) throws Exception {
        Map<String, String> map = new HashMap<>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(xmlData)));

        Element root = doc.getDocumentElement();
        NodeList nodeList = root.getChildNodes();

        for (int i = 0; i < nodeList.getLength(); i++) {
            map.put(nodeList.item(i).getNodeName(), nodeList.item(i).getTextContent());
        }

        return map;
    }
}